const fs = require('fs')
const path = require('path')
const { NodeSSH } = require('node-ssh')
const ssh = new NodeSSH()
const archiver = require('archiver')

// 配置信息
const config = {
  host: '47.94.179.81',
  port: 22, // 添加SSH端口，默认为22
  username: 'root',
  password: 'Shinow@123',
  // 也可尝试使用密钥认证
  // privateKey: fs.readFileSync('/path/to/private/key', 'utf8'),
  // passphrase: '如果你的密钥有密码，填写在这里',
  zipName: 'dist.zip',
  remoteDir: '/www/wwwroot/test_admin',
  // 增加重试和超时配置
  tryKeyboard: true, // 允许键盘交互式认证
  readyTimeout: 30000, // 延长连接超时时间
}

// 创建zip文件
function zipDist() {
  return new Promise((resolve, reject) => {
    console.log('正在创建zip文件...')
    const output = fs.createWriteStream(path.join(__dirname, `../${config.zipName}`))
    const archive = archiver('zip', { zlib: { level: 9 } })

    output.on('close', () => {
      console.log(`zip文件创建成功，大小: ${archive.pointer()} 字节`)
      resolve()
    })

    archive.on('error', (err) => {
      reject(err)
    })

    archive.pipe(output)
    archive.directory(path.join(__dirname, '../dist/assets'), 'assets')

    const files = ['index.html', 'index.html.gz']
    files.forEach((filename) => {
      archive.file(path.join(__dirname, '../dist/', filename), { name: filename })
    })
    archive.finalize()
  })
}

// 上传并解压
async function deployToServer() {
  try {
    // 1. 打包文件
    await zipDist()

    // 2. 连接到服务器
    console.log('正在连接到服务器...')

    await ssh.connect(config).catch(error => {
      console.error('SSH连接失败:', error.message)
      if (error.message.includes('All configured authentication methods failed')) {
        console.error('认证失败，请检查用户名、密码或密钥是否正确')
      }
      throw error
    })

    console.log('服务器连接成功')

    // 3. 上传zip文件
    console.log('正在上传zip文件...')
    await ssh.putFile(
      path.join(__dirname, `../${config.zipName}`),
      `${config.remoteDir}/${config.zipName}`
    )
    console.log('zip文件上传成功')

    // 4. 解压文件
    console.log('正在解压文件...')
    /*
    *  -o：强制覆盖已存在的文件。
    *  -d：指定解压目录。
    *  -q：静默模式，不显示解压过程。
    */
    const unzipResult = await ssh.execCommand(`cd ${config.remoteDir} && unzip -o ${config.zipName}`)
    if (unzipResult.stderr) {
      console.error('解压过程中出现错误:', unzipResult.stderr)
    }
    console.log('文件解压成功')

    // 5. 清理
    console.log('正在清理临时文件...')
    // await ssh.execCommand(`rm ${config.remoteDir}/${config.zipName}`)
    // fs.unlinkSync(path.join(__dirname, `../${config.zipName}`))

    console.log('部署完成！')
    ssh.dispose()
  } catch (error) {
    console.error('部署过程中出现错误:', error)
    ssh.dispose()
    process.exit(1)
  }
}

deployToServer() 